﻿namespace Atomic.Plugins.Users.ModelBinders
{
    using System.Linq;
    using System.Collections.Generic;
    using System.Web.Mvc;

    using Atomic.Extensions;
    using Atomic.Mvc.ModelBinders;
    using Atomic.Modules.Security;
    using Atomic.Plugins.Users.Exceptions;
    using Atomic.Plugins.Users.Domain.Admin;

    /// <summary>
    /// 角色授权数据绑定器。
    /// </summary>
    public class AuthorizeRoleModelBinder : ModelBinderProviderBase
    {
        /// <summary>
        /// 数据绑定到模型。
        /// </summary>
        /// <param name="controllerContext"></param>
        /// <param name="bindingContext"></param>
        /// <returns></returns>
        protected override object OnBindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var role = this.GetRole(controllerContext);

            role.SetPermissions(this.GetPermissions(controllerContext));

            AuthorizeRoleModel model = new AuthorizeRoleModel { Role = role };

            return model;
        }

        /// <summary>
        /// 获得角色信息。
        /// </summary>
        /// <param name="controllerContext"></param>
        /// <returns></returns>
        private Role GetRole(ControllerContext controllerContext)
        {
            var request = controllerContext.HttpContext.Request;

            if(!request.Form["role.Id"].IsNumeric())
            {
                throw new AuthorizeRoleException("获取不到 role.Id。");
            }

            var role = new Role()
            {
                Id = int.Parse(request.Form["role.Id"]),
            };

            return role;
        }

        /// <summary>
        /// 获得角色的授权信息。
        /// </summary>
        /// <param name="controllerContext"></param>
        /// <returns></returns>
        private IEnumerable<Permission> GetPermissions(ControllerContext controllerContext)
        {
            return (controllerContext.HttpContext.Request.Form["Permissions"] ?? string.Empty)
                .Split(',').Select(permissionString => this.GetPermission(permissionString)) ?? Enumerable.Empty<Permission>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="permissionString"></param>
        /// <returns></returns>
        private Permission GetPermission(string permissionString)
        {
            if (permissionString.IsNumeric())
            {
                return new Permission { Id = int.Parse(permissionString) };
            }

            return new NullPermission();
        }
    }
}